package dialog

import (
	"context"
	"github.com/templui/templui/internal/components/icon"
	"github.com/templui/templui/internal/utils"
)

type contextKey string

const (
	instanceKey contextKey = "dialogInstance"
	openKey     contextKey = "dialogOpen"
)

type Props struct {
	ID               string
	Class            string
	Attributes       templ.Attributes
	DisableClickAway bool
	DisableESC       bool
	Open             bool
}

type TriggerProps struct {
	ID         string
	Class      string
	Attributes templ.Attributes
	For        string // Reference to a specific dialog ID (for external triggers)
}

type ContentProps struct {
	ID               string
	Class            string
	Attributes       templ.Attributes
	HideCloseButton  bool
	Open             bool // Initial open state for standalone usage (when no context)
	DisableAutoFocus bool
}

type CloseProps struct {
	ID         string
	Class      string
	Attributes templ.Attributes
	For        string // ID of the dialog to close (optional, defaults to closest dialog)
}

type HeaderProps struct {
	ID         string
	Class      string
	Attributes templ.Attributes
}

type FooterProps struct {
	ID         string
	Class      string
	Attributes templ.Attributes
}

type TitleProps struct {
	ID         string
	Class      string
	Attributes templ.Attributes
}

type DescriptionProps struct {
	ID         string
	Class      string
	Attributes templ.Attributes
}

templ Dialog(props ...Props) {
	{{ var p Props }}
	if len(props) > 0 {
		{{ p = props[0] }}
	}
	{{ instanceID := p.ID }}
	if instanceID == "" {
		{{ instanceID = utils.RandomID() }}
	}
	{{ ctx = context.WithValue(ctx, instanceKey, instanceID) }}
	{{ ctx = context.WithValue(ctx, openKey, p.Open) }}
	<div
		if p.ID != "" {
			id={ p.ID }
		}
		data-tui-dialog
		data-dialog-instance={ instanceID }
		if p.DisableClickAway {
			data-tui-dialog-disable-click-away="true"
		}
		if p.DisableESC {
			data-tui-dialog-disable-esc="true"
		}
		class={ utils.TwMerge("", p.Class) }
		{ p.Attributes... }
	>
		{ children... }
	</div>
}

templ Trigger(props ...TriggerProps) {
	{{ var p TriggerProps }}
	if len(props) > 0 {
		{{ p = props[0] }}
	}
	{{ instanceID := "" }}
	// Explicit For prop takes priority over inherited context
	if p.For != "" {
		{{ instanceID = p.For }}
	} else if val := ctx.Value(instanceKey); val != nil {
		{{ instanceID = val.(string) }}
	}
	<span
		if p.ID != "" {
			id={ p.ID }
		}
		data-tui-dialog-trigger={ instanceID }
		data-dialog-instance={ instanceID }
		data-tui-dialog-trigger-open="false"
		class={ utils.TwMerge("contents", p.Class) }
		{ p.Attributes... }
	>
		{ children... }
	</span>
}

templ Content(props ...ContentProps) {
	{{ var p ContentProps }}
	if len(props) > 0 {
		{{ p = props[0] }}
	}
	// Start with prop values as defaults
	{{ instanceID := p.ID }}
	{{ open := p.Open }}
	// Override with context values if available
	if val := ctx.Value(instanceKey); val != nil {
		{{ instanceID = val.(string) }}
	}
	if val := ctx.Value(openKey); val != nil {
		{{ open = val.(bool) }}
	}
	// Apply defaults if still empty
	if instanceID == "" {
		{{ instanceID = utils.RandomID() }}
	}
	<!-- Overlay -->
	<div
		class={ utils.TwMerge(
				"fixed inset-0 z-50 bg-black/50",
				"transition-opacity duration-300",
				"data-[tui-dialog-open=false]:opacity-0",
				"data-[tui-dialog-open=true]:opacity-100",
				"data-[tui-dialog-open=false]:pointer-events-none",
				"data-[tui-dialog-open=true]:pointer-events-auto",
				"data-[tui-dialog-hidden=true]:!hidden",
			) }
		data-tui-dialog-backdrop
		data-dialog-instance={ instanceID }
		if open {
			data-tui-dialog-open="true"
		} else {
			data-tui-dialog-open="false"
			data-tui-dialog-hidden="true"
		}
	></div>
	<!-- Content -->
	<div
		class={
			utils.TwMerge(
				// Base positioning
				"fixed z-50 left-[50%] top-[50%] translate-x-[-50%] translate-y-[-50%]",
				// Style
				"bg-background rounded-lg border shadow-lg",
				// Layout
				"grid gap-4 p-6",
				// Size
				"w-full max-w-[calc(100%-2rem)] sm:max-w-lg",
				// Transitions
				"transition-all duration-200",
				// Scale animation
				"data-[tui-dialog-open=false]:scale-95",
				"data-[tui-dialog-open=true]:scale-100",
				// Opacity
				"data-[tui-dialog-open=false]:opacity-0",
				"data-[tui-dialog-open=true]:opacity-100",
				// Pointer events
				"data-[tui-dialog-open=false]:pointer-events-none",
				"data-[tui-dialog-open=true]:pointer-events-auto",
				// Hidden state
				"data-[tui-dialog-hidden=true]:!hidden",
				p.Class,
			),
		}
		data-tui-dialog-content
		data-dialog-instance={ instanceID }
		if p.DisableAutoFocus {
			data-tui-dialog-disable-autofocus="true"
		}
		if open {
			data-tui-dialog-open="true"
		} else {
			data-tui-dialog-open="false"
			data-tui-dialog-hidden="true"
		}
		{ p.Attributes... }
	>
		{ children... }
		if !p.HideCloseButton {
			<button
				class={ utils.TwMerge(
						// Positioning
						"absolute top-4 right-4",
						// Style
						"rounded-xs opacity-70",
						// Interactions
						"transition-opacity hover:opacity-100",
						// Focus states
						"focus:outline-none focus:ring-2",
						"focus:ring-ring focus:ring-offset-2",
						"ring-offset-background",
						// Hover/Data states
						"data-[tui-dialog-open=true]:bg-accent",
						"data-[tui-dialog-open=true]:text-muted-foreground",
						// Disabled state
						"disabled:pointer-events-none",
						// Icon styles
						"[&_svg]:pointer-events-none",
						"[&_svg]:shrink-0",
						"[&_svg:not([class*='size-'])]:size-4",
					) }
				data-tui-dialog-close={ instanceID }
				aria-label="Close"
				type="button"
			>
				@icon.X()
				<span class="sr-only">Close</span>
			</button>
		}
	</div>
}

templ Close(props ...CloseProps) {
	{{ var p CloseProps }}
	if len(props) > 0 {
		{{ p = props[0] }}
	}
	<span
		if p.ID != "" {
			id={ p.ID }
		}
		if p.For != "" {
			data-tui-dialog-close={ p.For }
		} else {
			data-tui-dialog-close
		}
		class={ utils.TwMerge("contents cursor-pointer", p.Class) }
		{ p.Attributes... }
	>
		{ children... }
	</span>
}

templ Header(props ...HeaderProps) {
	{{ var p HeaderProps }}
	if len(props) > 0 {
		{{ p = props[0] }}
	}
	<div
		if p.ID != "" {
			id={ p.ID }
		}
		class={ utils.TwMerge("flex flex-col gap-2 text-center sm:text-left", p.Class) }
		{ p.Attributes... }
	>
		{ children... }
	</div>
}

templ Footer(props ...FooterProps) {
	{{ var p FooterProps }}
	if len(props) > 0 {
		{{ p = props[0] }}
	}
	<div
		if p.ID != "" {
			id={ p.ID }
		}
		class={ utils.TwMerge("flex flex-col-reverse gap-2 sm:flex-row sm:justify-end", p.Class) }
		{ p.Attributes... }
	>
		{ children... }
	</div>
}

templ Title(props ...TitleProps) {
	{{ var p TitleProps }}
	if len(props) > 0 {
		{{ p = props[0] }}
	}
	<h2
		if p.ID != "" {
			id={ p.ID }
		}
		class={ utils.TwMerge("text-lg leading-none font-semibold", p.Class) }
		{ p.Attributes... }
	>
		{ children... }
	</h2>
}

templ Description(props ...DescriptionProps) {
	{{ var p DescriptionProps }}
	if len(props) > 0 {
		{{ p = props[0] }}
	}
	<p
		if p.ID != "" {
			id={ p.ID }
		}
		class={ utils.TwMerge("text-muted-foreground text-sm", p.Class) }
		{ p.Attributes... }
	>
		{ children... }
	</p>
}
